#lang racket

(define lambdaA (lambda (x)
                        (+ x x)))

; Combine Lambda expression and let expression
; In difference place The "Double" meaning is difference parameter.
; lambda using for define nondetermine procedure.
(let ([Double (lambda (x) (+ x x))])
  (list (Double (* 3 4))
        (Double (/ 99 11)) 
        (Double (- 2 7))))

(let ([Double-cons (lambda (x)(cons x x))])
  (list (Double-cons 'a)
        (Double-cons 'b)
        (Double-cons 'c)))

; nest let and Lambda

(let ([x 'a])
  (let ([f (lambda (y) (list x y))])
    (f 'b)))

(define TellYourName
  (let ([f (let ([x '(Hello )])
             (lambda (name)
               (list x name)))])f))


;Exercise 2.5.1
;(let ([f (lambda ( x y) y)])
;  (f 'a))


(define proc1 cons)

(define proc2
  (lambda (x y)
    (proc1 x y)))


; using lambda experssion 
(define compose
  (lambda (f1 f2 v1)
        (f1 (f2 v1))))
(define CADR (lambda (x)
               (compose cdr car x)))
(define CDDR (lambda (x)
               (compose cdr cdr x)))
(define CAAR (lambda (x)
                (compose car car x)))
(define CDAR (lambda (x)
               (compose car cdr x)))
(define CAAAR (lambda (x)
                (compose car CAAR x)))
(define CAADR (lambda (x)
                (compose cdr CAAR x)))


(define listA (cons (cons 'a 'b)(cons 'c 'd)))

; Define Atom? procedure to determine x is or not basic type
(define Atom?
  (lambda (x)
    (cond
      [(null? x) "Parameter is empty"]
      [(pair? x) false]
      [else true])))

; Define make-list
;(define make-list
; (lambda (n ojbect)
;   (if (= n 0)
;       '()
;   ((list ojbect (make-list (- n 1) ojbect))))))






